package com.juc.interrupt;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @Author Zan
 * @Create 2024/5/8 16:30
 * @ClassName : InterruptDemo
 * @Description : 面试题：如何使用中断标识停止线程？
 */
public class InterruptDemo {

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println(Thread.currentThread().getName() + "\t isInterrupted被修改为true，程序停止");
                    break;
                }
                System.out.println("t1 -----hello interrupted");
            }
        }, "t1");
        t1.start();

        System.out.println("------t1的默认中断标志位：" + t1.isInterrupted());

        TimeUnit.MILLISECONDS.sleep(20);

        new Thread(() -> {
            t1.interrupt(); // 发出中断协商的申请 - 将其改为true
        }, "t2").start();
    }

    private static AtomicBoolean atomicBoolean = new AtomicBoolean(false);

    private static void m2_atomicBoolean() throws InterruptedException {
        new Thread(() -> {
            while (true) {
                if (atomicBoolean.get()) {
                    System.out.println(Thread.currentThread().getName() + "\t atomicBoolean被修改为true，程序停止");
                    break;
                }
                System.out.println("t1 -----hello atomicBoolean");
            }
        }, "t1").start();

        TimeUnit.MILLISECONDS.sleep(20);

        new Thread(() -> {
            atomicBoolean.set(true);
        }, "t2").start();
    }


    // volatile 可见性
    // 它会保证修改的值会立即被更新到主存，当有其他线程需要读取时，它会去内存中读取新值。
    // 而普通的共享变量不能保证可见性，因为普通共享变量被修改之后，什么时候被写入主存是不确定的，当其他线程去读取时，此时内存中可能还是原来的旧值，因此无法保证可见性。
    private volatile static boolean isStop = false;

    private static void m1_volatile() throws InterruptedException {
        new Thread(() -> {
            while (true) {
                if (isStop) {
                    System.out.println(Thread.currentThread().getName() + "\t isStop被修改为true，程序停止");
                    break;
                }
                System.out.println("t1 -----hello volatile");
            }
        }, "t1").start();

        TimeUnit.MILLISECONDS.sleep(20);

        new Thread(() -> {
            isStop = true;
        }, "t2").start();
    }
}
